﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Xml.Serialization;

namespace Library.Models
{
    [DataContract]
    [XmlInclude(typeof(TermDevice))]
    [XmlInclude(typeof(InDevice))]
    [XmlInclude(typeof(OutDevice))]
    [XmlInclude(typeof(InOutDevice))]
    [KnownType(typeof(TermDevice))]
    [KnownType(typeof(InDevice))]
    [KnownType(typeof(OutDevice))]
    [KnownType(typeof(InOutDevice))]
    public abstract class TwiDevice
    {
        [DataMember]
        [Description("Adres TWI")]
        public int Address { get; set; }

        [DataMember]
        [Description("Opis")]
        public string Description { get; set; }

        //[DataMember]
        //[Description("Typ")]
        //public int Type { get; set; }

        public override string ToString()
        {
            return "Address: " + Address +", Description: " + Description;
        }
    }

    [DataContract]
    public class TermDevice : TwiDevice
    {
        [DataMember]
        [XmlIgnore]
        public double Temp { get; set; }

        public override string ToString()
        {
            return "TermDevice: " + base.ToString() + " temp: " + this.Temp.ToString("0.000");
        }
    }

    [DataContract]
    public class InDevice : TwiDevice
    {
        public InDevice()
        {
            Pins = new List<DevicePin>();
        }

        [DataMember]
        public List<DevicePin> Pins { get; set; }

        public override string ToString()
        {
            string ret = "|" + this.Pins.OrderBy(p => p.Pin).Aggregate("|", (current, pin) => current + pin.Pin + ":" + (pin.Value == true ? "1" : "0") + "|");
            return "InDevice: " + base.ToString() + " pins: " + ret;
        }
    }

    [DataContract]
    public class OutDevice : TwiDevice
    {
        public OutDevice()
        {
            Pins = new List<DevicePin>();
        }

        [DataMember]
        public List<DevicePin> Pins { get; set; }

        public override string ToString()
        {
            string ret = "|" + this.Pins.OrderBy(p => p.Pin).Aggregate("|", (current, pin) => current + pin.Pin + ":" + (pin.Value == true ? "1" : "0") + "|");
            return "OutDevice: " + base.ToString() + " pins: " + ret;
        }
    }

    [DataContract]
    public class InOutDevice : TwiDevice
    {
        public InOutDevice()
        {
            Pins = new List<DevicePin>();
        }

        [DataMember]
        public List<DevicePin> Pins { get; set; }

        public override string ToString()
        {
            string ret = "|" + this.Pins.OrderBy(p => p.Pin).Aggregate("|", (current, pin) => current + pin.Pin + ":" + (pin.Value == true ? "1" : "0") + "|");
            return "InOutDevice: " + base.ToString() + " pins: " + ret;
        }
    }



    [DataContract]
    public class DevicePin
    {
        public DevicePin()
        {
            Value = false;
        }

        [DataMember]
        public byte Pin { get; set; }

        [DataMember]
        [XmlIgnore]
        public bool Value { get; set; }

        [DataMember]
        public string Name { get; set; }
    }



    [DataContract]
    public class TwiDeviceList
    {
        public TwiDeviceList()
        {
            List = new List<TwiDevice>();
        }

        [DataMember]
        public List<TwiDevice> List { get; set; }
    }

    public enum DeviceType
    {
        Pcf = 1,
        Light = 2,
        Temp = 3
    }
}